﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SalesSys.Comm.Utility
{
    public class ValidateException : ArgumentException
    {
        public ValidateException() { }

        public ValidateException(string msg)
            : base(msg)
        {
        }

    }
    public class FastCheck
    {
        /// <summary>
        /// 断言，失败抛出验证错误异常
        /// </summary>
        /// <param name="isOk"></param>
        /// <param name="msg"></param>
        public static void Required(bool isOk, string msg = null)
        {

            if (!isOk)
                throw new ValidateException(msg);
        }

        /// <summary>
        /// 判断是否有空字符，有的话返回索引，没有的话返回-1，如果数组为null则返回-2
        /// </summary>
        /// <param name="strArray"></param>
        /// <returns></returns>
        public static int IndexOfNullOrWhiteSpace(params string[] strArray)
        {
            if (strArray==null)
            {
                return -2;
            }
            for (int i = 0; i <strArray.Length; i++)
            {
                if (string.IsNullOrWhiteSpace(strArray[i]))
                {
                    return i;
                }
            }
            return -1;
        }
        public const char accountAllowChar = '_';
        /// <summary>
        /// 是符合帐号名规则，
        /// </summary>
        /// <param name="accountName"></param>
        /// <param name="allowChars"></param>
        /// <returns></returns>
        public static KeyValuePair<bool, string> IsAccountName(string accountName, params char[] allowChars)
        {
            if (string.IsNullOrWhiteSpace(accountName) || accountName.Length < 5)
            {
                return new KeyValuePair<bool, string>(false, "用户名长度至少5个字符");
            }
            if (!(char.IsLetter(accountName[0]) || accountName[0] == accountAllowChar))
            {
                return new KeyValuePair<bool, string>(false, "登录名必须以字母或下划线开头");
            }
            var ret = false;
            if (allowChars == null || allowChars.Length < 1)
            {
                ret = accountName.All(p => char.IsLetterOrDigit(p) || p == accountAllowChar);
            }
            else
            {
                ret = accountName.All(p => char.IsLetterOrDigit(p) || p == accountAllowChar || allowChars.Any(x => x == p));
            }
            if (ret)
            {
                return new KeyValuePair<bool, string>(true, null);
            }
            else
            {
                return new KeyValuePair<bool, string>(false, "包含非法字符");
            }

        }



        #region 正则表达式

        /// <summary>
        /// 是否电子邮件
        /// </summary>
        public static bool IsEmail(string value)
        {
            const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否是IP地址
        /// </summary>
        public static bool IsIpAddress(string value)
        {
            const string pattern = @"^(\d(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\d\.){3}\d(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\d$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否是整数
        /// </summary>
        public static bool IsNumeric(string value)
        {
            const string pattern = @"^\-?[0-9]+$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否是Unicode字符串
        /// </summary>
        public static bool IsUnicode(string value)
        {
            const string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否Url字符串
        /// </summary>
        public static bool IsUrl(string value)
        {
            const string pattern = @"^(http|https|ftp|rtsp|mms):(\/\/|\\\\)[A-Za-z0-9%\-_@]+\.[A-Za-z0-9%\-_@]+[A-Za-z0-9\.\/=\?%\-&_~`@:\+!;]*$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否身份证号，验证如下3种情况：
        /// 1.身份证号码为15位数字；
        /// 2.身份证号码为18位数字；
        /// 3.身份证号码为17位数字+1个字母
        /// </summary>
        public static bool IsIdentityCard(string value)
        {
            const string pattern = @"^(^\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否手机号码
        /// </summary>
        /// <param name="value"></param>
        /// <param name="isRestrict">是否按严格格式验证</param>
        public static bool IsMobileNumber(string value, bool isRestrict = true)
        {
            string pattern = isRestrict ? @"^[1][3-8]\d{9}$" : @"^[1]\d{10}$";
            return value.IsMatch(pattern);
        }

        /// <summary>
        /// 是否用户密码 以字母开头，长度在6~18之间，只能包含字符、数字和下划线
        /// </summary>
        /// <param name="value"></param>
        /// <param name="isRestrict">是否按严格格式验证</param>
        public static bool IsPassword(string value, bool isRestrict = true)
        {
            const string pattern = @"^[a-zA-Z]\w{5,17}$";
            return value.IsMatch(pattern);
        }
        /// <summary>
        /// 4-16字符【每个中文按2个字符计算】，可以包含下划线。
        /// </summary>
        /// <returns></returns>
        public static bool IsUserName(string value, bool isRestrict = true)
        {
            const string pattern = @"^[\w|\u4e00-\u9fa5]*$";
 
            int bytelen = GetStrLength(value);
            if (bytelen > 16 || bytelen < 4)
            {
                return false;
            }
            return value.IsMatch(pattern);
        }
        public static int GetStrLength(string sStr)
        {
            int rvalue = 0;
            if (sStr != null)
            {
                rvalue = Encoding.GetEncoding("gb2312").GetByteCount(sStr);
            }
            return rvalue;
        }
        #endregion

        /// <summary>
        /// 修正页大小到指定范围,pagesize最大为100，默认30
        /// </summary>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static bool FixPagingConfig(ref int pageNum, ref int pageSize, int defSize = 30)
        {
            bool isHandle = false;
            int sizeMax = 100;
            if (pageSize > sizeMax)
            {
                pageSize = sizeMax;
                isHandle = true;
            }
            if (pageSize < 1)
            {
                pageSize = defSize;
                isHandle = true;
            }
            if (pageNum < 1)
            {
                pageNum = 1;
                isHandle = true;
            }
            return isHandle;
        }

    }
}
